<html>
    <head>
        <meta charset="utf-8">
        <title>使用DoMonit监控Docker</title>
        <link rel="stylesheet" href="../assets/stylesheets/global.css">
        <link rel="stylesheet" href="../assets/stylesheets/words.css">
        <link rel="stylesheet" href="../assets/stylesheets/monokai.css">
        <link rel="stylesheet" href="../assets/stylesheets/table.css">
        <link rel="shortcut icon" href="../assets/images/favicon.ico" type="image/x-icon">
        <link rel="icon" href="../assets/images/favicon.ico" type="image/x-icon">
        <script>
            // 统计代码
            (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
                m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
                })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

            ga('create', 'UA-93231524-1', 'auto');
            ga('send', 'pageview');
        </script>
    </head>
    <body>
        <div id="header">
            <a href="../index.html"><div id="logo">JG</div></a>
        </div>
        <div id="container" class="typo">
            <div id="article">
                <h1>使用DoMonit监控Docker</h1>
                <h4>Posted August 17, 2016</h4>

                <p>本篇的目的是介绍Python包<a href="https://github.com/eon01/DoMonit">Domonit</a>, 一个基于Python语言开发的API封装的轻量监控程序.</p>

<p>监控可以让你可视化服务的基础架构, 生产环境不进行监控是不推荐的. 同样生产环境的Docker也需要监控, 特别是很多容器运行了关键的服务.</p>

<p>管理生产环境下的linux系统超过十年, 我有部署测试了很多基础架构和生产监控系统。从我经验来看, 采取云基础架构管理, 改变了我们使用管理基础架构的方式. 我想说即使问题的性质正在改变, 产品的质量变的更加重要，关键的监控也变的更积极主动,监控并不仅仅是收集和可视化哪些指标而意识到发生了什么. 在大多情况下, 监控是基于某个特别的用例和环境下(比如: 基于业务逻辑)。 这就是在某些情况下我实用脚本来编写监控程序, 我几乎都是使用Python， 有时使用Bash.</p>
<blockquote class="blockquote-normal">
                <p>译者注: 大概意思就是云的出现， 一些基础的监控收集指标数据并且可视化的事情云服务提供商已经做了, 之后更多可能就是基于特定的场景进行监控, 这个时候没有通用的模版来监控, 只能自己写脚本来监控, 这个感触我太了解了， 因为我曾经写过两年的监控脚本</p></blockquote>
<p>在我关于Docker的实验工作中, <a href="https://docs.docker.com/swarm/">Docker Swarm</a> 和 Micro Services运行在Docker上. 我需要一个可以让我在自己编写的脚本使用获取监控指标的监控工具, 我通过此工具自定义一些监控指标和监控逻辑。 这就是我为什么要使用<a href="https://github.com/eon01/DoMonit">Domonit</a>。 先看一下DoMonit是什么?</p>

<p>此工具用Python 封装了Docker API, 提供了更优雅的Python接口供您脚本调用获取Docker相关的数据. 基于Docker API 1.24版本封装, 兼容监控Docker版本1.12.x及以上的docker版本.</p>

<p><p class="hassubimage"><img src="/uploads/images/ashdod-port-aerial-view.jpeg" alt=""></p>
                    <p class="img-title">码头鸟瞰图</p></p>

<h2>DoMonit 目的</h2>

<p>其目的是让你很容易的通过python编写方便监控Docker 所有容器的脚本， 搜集所有需要的指标数据,  </p>
<blockquote class="blockquote-normal">
                <p>The Github repository of Domonit is : https://github.com/eon01/DoMonit</p></blockquote>
<h2>封装信息</h2>
<div class="code-wrapper"><span class="lang-label">Bash</span><div class="highlight"><pre><span></span>api/
├── changes.py
├── containers.py
├── errors.py
├── ids.py
├── inspect.py
├── logs.py
├── process.py
└── stats.py
</pre></div>
</div><div class="table-wrapper"><table class="ui selectable celled table"><thead>
<tr>
<th>api</th>
<th>说明</th>
</tr>
</thead>

<tbody>
<tr>
<td><strong>containers</strong></td>
<td>容器列表</td>
</tr>
<tr>
<td><strong>inspect</strong></td>
<td>返回指定id容器的基础信息</td>
</tr>
<tr>
<td><strong>ids</strong></td>
<td>返回容器id列表</td>
</tr>
<tr>
<td><strong>logs</strong></td>
<td>返回指定id容器的stdout和stderr日志</td>
</tr>
<tr>
<td><strong>process</strong></td>
<td>列出此容器中运行的进程信息, 在unix系统中通过ps命令完成的, 所以此功能不支持windows</td>
</tr>
<tr>
<td><strong>stats</strong></td>
<td>返回关于此容器的使用统计的实时数据</td>
</tr>
</tbody>
</table></div>
<h2>使用样例</h2>

<p>创建虚拟环境 克隆项目</p>
<div class="code-wrapper"><span class="lang-label">Bash</span><div class="highlight"><pre><span></span>virtualenv domonit
<span class="nb">cd</span> domonit 
. bin/activate
git clone https://github.com/eon01/DoMonit.git
<span class="nb">cd</span> DoMonit
pip install -r requirements.txt
python examples.py
</pre></div>
</div>
<p><code>examples.py</code></p>
<div class="code-wrapper"><span class="lang-label">Python</span><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">api.containers</span> <span class="kn">import</span> <span class="n">Containers</span>
<span class="kn">from</span> <span class="nn">api.ids</span> <span class="kn">import</span> <span class="n">Ids</span>
<span class="kn">from</span> <span class="nn">api.inspect</span> <span class="kn">import</span> <span class="n">Inspect</span>
<span class="kn">from</span> <span class="nn">api.logs</span> <span class="kn">import</span> <span class="n">Logs</span>
<span class="kn">from</span> <span class="nn">api.process</span> <span class="kn">import</span> <span class="n">Process</span>
<span class="kn">from</span> <span class="nn">api.changes</span> <span class="kn">import</span> <span class="n">Changes</span>
<span class="kn">from</span> <span class="nn">api.stats</span> <span class="kn">import</span> <span class="n">Stats</span>

<span class="kn">import</span> <span class="nn">json</span>

<span class="n">c</span> <span class="o">=</span> <span class="n">Containers</span><span class="p">()</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">Ids</span><span class="p">()</span>
<span class="k">print</span> <span class="p">(</span><span class="s2">&quot;Number of containers is : </span><span class="si">%s</span><span class="s2"> &quot;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">sum</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">i</span><span class="o">.</span><span class="n">ids</span><span class="p">())))</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="k">for</span> <span class="n">c_id</span> <span class="ow">in</span> <span class="n">i</span><span class="o">.</span><span class="n">ids</span><span class="p">():</span>
        <span class="n">ins</span> <span class="o">=</span> <span class="n">Inspect</span><span class="p">(</span><span class="n">c_id</span><span class="p">)</span>
        <span class="n">sta</span> <span class="o">=</span> <span class="n">Stats</span><span class="p">(</span><span class="n">c_id</span><span class="p">)</span>
        <span class="n">proc</span> <span class="o">=</span> <span class="n">Process</span><span class="p">(</span><span class="n">c_id</span><span class="p">,</span> <span class="n">ps_args</span> <span class="o">=</span> <span class="s2">&quot;aux&quot;</span><span class="p">)</span>
        <span class="c1"># Container name</span>
        <span class="k">print</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">#Container name&quot;</span><span class="p">)</span>
        <span class="k">print</span> <span class="n">ins</span><span class="o">.</span><span class="n">name</span><span class="p">()</span>
        <span class="c1"># Container id</span>
        <span class="k">print</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">#Container id&quot;</span><span class="p">)</span>
        <span class="k">print</span> <span class="n">ins</span><span class="o">.</span><span class="n">id</span><span class="p">()</span>
        <span class="c1"># Memory usage</span>
        <span class="n">mem_u</span> <span class="o">=</span> <span class="n">sta</span><span class="o">.</span><span class="n">usage</span><span class="p">()</span>
        <span class="c1"># Memory limit</span>
        <span class="n">mem_l</span> <span class="o">=</span> <span class="n">sta</span><span class="o">.</span><span class="n">limit</span><span class="p">()</span>
        <span class="c1"># Memory usage %</span>
        <span class="k">print</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">#Memory usage %&quot;</span><span class="p">)</span>
        <span class="k">print</span>  <span class="nb">int</span><span class="p">(</span><span class="n">mem_u</span><span class="p">)</span><span class="o">*</span><span class="mi">100</span><span class="o">/</span><span class="nb">int</span><span class="p">(</span><span class="n">mem_l</span><span class="p">)</span>

        <span class="c1"># The number of times that a process of the cgroup triggered a &quot;major fault&quot;</span>
        <span class="k">print</span> <span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">#The number of times that a process of the cgroup triggered a major fault&quot;</span><span class="p">)</span>
        <span class="k">print</span> <span class="n">sta</span><span class="o">.</span><span class="n">pgmajfault</span><span class="p">()</span>

        <span class="c1"># Same output as ps aux in *nix</span>
        <span class="k">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">#Same output as ps aux in *nix&quot;</span><span class="p">)</span>
        <span class="k">print</span> <span class="n">proc</span><span class="o">.</span><span class="n">ps</span><span class="p">()</span>
</pre></div>
</div>
<p>我有五个容器， 出于简单， 我省略了其他的，保留1个输出信息.</p>

        
<div class="highlight"><pre>Number of containers is : 5 
#Container name
/vote_webapp_1
#Container id
1a29e9652822447a440799306f4edb65003bca9cdea4c56e1e0ba349d5112d3e
#Memory usage %
0.697797903077
#The number of times that a process of the cgroup triggered a major fault
15
#Same output as ps aux in *nix
{u'Processes': [[u'root', u'26636', u'0.0', u'0.2', u'76808', u'16228', u'?', u'Ss', u'15:43', u'0:00', u'/usr/local/bin/python2 /usr/local/bin/gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0'], [u'root', u'26773', u'0.0', u'0.2', u'88776', u'19976', u'?', u'S', u'15:43', u'0:00', u'/usr/local/bin/python2 /usr/local/bin/gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0'], [u'root', u'26784', u'0.0', u'0.2', u'88572', u'19800', u'?', u'S', u'15:43', u'0:00', u'/usr/local/bin/python2 /usr/local/bin/gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0'], [u'root', u'26787', u'0.0', u'0.2', u'88568', u'19816', u'?', u'S', u'15:43', u'0:00', u'/usr/local/bin/python2 /usr/local/bin/gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0'], [u'root', u'26793', u'0.0', u'0.2', u'88572', u'19828', u'?', u'S', u'15:43', u'0:00', u'/usr/local/bin/python2 /usr/local/bin/gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0']], u'Titles': [u'USER', u'PID', u'%CPU', u'%MEM', u'VSZ', u'RSS', u'TTY', u'STAT', u'START', u'TIME', u'COMMAND']}
[..etc..]</pre></div>

            </div>
            <div id="footer">
                <a href="../words.html"><div id="more-words">MORE WORDS</div></a>
            </div>
        </div>
    </body>
</html>